<?php
/**
 * Copyright (c) 2006, PORTALIER Julien
 *
 * Licensed under The LGPL License
 * Redistributions of files must retain the above copyright notice.
 *
 * @package      Feather's website
 * @copyright    Copyright (c) 2006, Julien PORTALIER
 * @link         http://feather.portalier.com
 * @license      http://www.opensource.org/licenses/lgpl-license.php The LGPL License
 */

abstract class TagModel extends Model
{
	public $recursiveProcess = Q_PROCESS_LIST;
	public $recursiveFields  = 'tag';
	public $tagName = 'tag';
	
	protected $refererClass;
	
	function getCloud($limit=null)
	{
		$referer = $this->{$this->refererClass};
		
		// prepares query
		$fields = array(
			"{$this->name}.{$this->tagName}",
			'-! COUNT( '.$this->db->field("{$referer->name}.{$referer->primaryKey}").' ) AS '.$this->db->field('tagcounter')
		);
		$this->groupby("GROUP BY {$this->name}.{$this->tagName}");
		$this->order('tagcounter DESC');
		
		// query
		$this->recursive = 0;
		$this->process   = Q_PROCESS_LITE;
		$_tags = $this->findAll(&$fields, $limit);
		
		// generates tag cloud ready array
		$tags = array();
		foreach ($_tags as $tag)
			$tags[$tag[$this->tagName]] = $tag['tagcounter'];
		ksort($tags);
		
		return $tags;
	}
	
	function __save($type=null)
	{
		$referer = $this->{$this->refererClass};
		
		// tags
		$tags = $this->data[$this->name][$this->tagName];
		
		// removed all tags?
		if (empty($tags))
		{
			$this->conditions(array($referer->foreignKey => $referer->id));
			$this->__delete();
			return true;
		}
		elseif (is_string($tags)) {
			$tags = explode(',', $tags);
		}
		
		$tags = array_unique($tags);
		foreach($tags as $i => $tag)
		{
			$tag = trim($tag);
			if (!empty($tag))
				$tags[$i] = $tag;
			else
				unset($tags[$i]);
		}
		
		// already sticked tags
		$this->conditions(array($referer->foreignKey => $referer->id));
		$_tags = $this->listField($this->tagName, -1);
		
		$new_tags = array_diff($tags, $_tags);
		$del_tags = array_diff($_tags, $tags);
		
		// deletes removed tags
		foreach($del_tags as $tag)
		{
			$this->conditions(array(
				$referer->foreignKey => $referer->id,
				$this->tagName => $tag
			));
			if (!$this->__delete())
				return false;
		}
		
		// saves new tags
		if (!empty($new_tags))
		{
			$values = array();
			foreach($new_tags as $tag)
			{
				$entry = array($referer->id, $tag);
				array_push($values, $entry);
			}
			if (!$this->saveMany(array($referer->foreignKey, $this->tagName), &$values))
				return false;
		}
		
		return $this->afterSave();
	}
	
	// admin
	
	function rename($old, $new)
	{
		$this->conditions(array('tag' => $old));
		return $this->saveField('tag', $new);
	}
}
?>